package com.zhijian.medical.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.google.common.collect.Lists;
import com.zhijian.medical.dao.local.MonitorModuleMapper;
import com.zhijian.medical.entity.po.MonitorModule;
import com.zhijian.medical.entity.po.Product;
import com.zhijian.medical.entity.vo.request.LocatorRecordSearchVo;
import com.zhijian.medical.entity.vo.request.MonitorModuleSearchVo;
import com.zhijian.medical.entity.vo.request.ProductSendOutDetailBatchSearchVo;
import com.zhijian.medical.entity.vo.request.TemperatureRecordSearchVo;
import com.zhijian.medical.entity.vo.response.*;
import com.zhijian.medical.service.*;
import com.zhijian.medical.util.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 监测模块业务处理层
 *
 * @author HCG
 * @version: 1.0
 * @date 2022-03-12 12:40:15
 */
@Slf4j
@Service
public class MonitorModuleServiceImpl implements MonitorModuleService {

    @Autowired
    private MonitorModuleMapper mapper;

    @Autowired
    private ProductService productService;

    @Autowired
    private ProductSendOutDetailBatchService productSendOutDetailBatchService;

    @Autowired
    private TemperatureRecordService temperatureRecordService;

    @Autowired
    private LocatorRecordService locatorRecordService;

    @Override
    public MonitorModule selectById(Long id) {
        return mapper.selectByPrimaryKey(id);
    }

    @Override
    public MonitorModuleVo selectVoById(Long id) {
        return mapper.selectVoById(id);
    }

    @Override
    public void deleteById(Long id) {
        mapper.deleteByPrimaryKey(id);
    }

    @Override
    public Long insert(MonitorModule monitorModule) {
        monitorModule.setSort(getNextSort());
        Date now = new Date();
        monitorModule.setCreateTime(now);
        monitorModule.setUpdateTime(now);
        return mapper.insert(monitorModule) > 0 ? monitorModule.getId() : 0L;
    }

    @Override
    public boolean update(MonitorModule monitorModule) {
        Date now = new Date();
        monitorModule.setUpdateTime(now);
        return mapper.updateByPrimaryKey(monitorModule) != 0;
    }

    @Override
    public Integer count(MonitorModuleSearchVo monitorModuleSearchVo) {
        return mapper.count(monitorModuleSearchVo);
    }

    @Override
    public List<MonitorModuleVo> selectList(MonitorModuleSearchVo monitorModuleSearchVo) {
        return mapper.selectList(monitorModuleSearchVo);
    }

    @Override
    public Page<MonitorModuleVo> selectPage(MonitorModuleSearchVo monitorModuleSearchVo) {
        //先直接查总数
        int count = count(monitorModuleSearchVo);
        //分页
        Page<MonitorModuleVo> page = new Page<>(true, count, monitorModuleSearchVo.getPageNum(), monitorModuleSearchVo.getPageSize());
        monitorModuleSearchVo.setStartIndex(page.getStartIndex());
        page.setPage(true);
        page.setTotalCount(count);
        List<MonitorModuleVo> responseVos = this.selectList(monitorModuleSearchVo);
        page.setData(responseVos);
        return page;
    }

    @Override
    public List<MonitorModuleVo> selectListByProductId(Long productId) {
        //先查产品订单表，拿到关联的厂家id
        Product product = productService.selectById(productId);
        if (Objects.isNull(product) || Objects.isNull(product.getFactoryId())) {
            return Collections.emptyList();
        }
        return this.selectList(MonitorModuleSearchVo.builder()
                .factoryId(product.getFactoryId())
                .build());
    }

    @Override
    public Integer selectMaxSort() {
        return mapper.selectMaxSort();
    }

    @Override
    public Integer getNextSort() {
        Integer maxSort = this.selectMaxSort();
        return Objects.nonNull(maxSort) ? maxSort + 1 : 1;
    }

    @Override
    public List<MonitorModuleTraceVo> selectMonitorModuleTraceVoListByProductSendOutDetailId(Long productIdSendOutDetailId) {
        List<ProductSendOutDetailBatchVo> productSendOutDetailBatchVos = productSendOutDetailBatchService.selectList(ProductSendOutDetailBatchSearchVo.builder()
                .detailId(productIdSendOutDetailId)
                .build());
        if (CollectionUtil.isEmpty(productSendOutDetailBatchVos)) {
            return Collections.emptyList();
        }
        //过滤一下，只找有关联模块id的数据
        productSendOutDetailBatchVos = productSendOutDetailBatchVos.stream().filter(productSendOutDetailBatchVo -> Objects.nonNull(productSendOutDetailBatchVo.getMonitorModuleId())).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(productSendOutDetailBatchVos)) {
            return Collections.emptyList();
        }
        List<MonitorModuleTraceVo> result = Lists.newArrayList();

        productSendOutDetailBatchVos.forEach(productSendOutDetailBatchVo -> {
            MonitorModule monitorModule = this.selectById(productSendOutDetailBatchVo.getMonitorModuleId());
            if (Objects.nonNull(monitorModule) && Objects.nonNull(monitorModule.getModuleId())) {
                String startTime = productSendOutDetailBatchVo.getStartTime();
                String endTime = productSendOutDetailBatchVo.getEndTime();
                //一周的温度轨迹
                List<TemperatureRecordVo> temperatureRecordVoList = temperatureRecordService.selectList(TemperatureRecordSearchVo.builder()
                        .thingId(monitorModule.getModuleId())
                        .createTimeStart(startTime)
                        .createTimeEnd(endTime)
                        .build());
                //一周的位置轨迹
                List<LocatorRecordVo> locatorRecordVoList = locatorRecordService.selectList(LocatorRecordSearchVo.builder()
                        .thingId(monitorModule.getModuleId())
                        .createTimeStart(startTime)
                        .createTimeEnd(endTime)
                        .build());
                result.add(MonitorModuleTraceVo.builder()
                        .temperatureRecordList(temperatureRecordVoList)
                        .locatorRecordList(locatorRecordVoList)
                        .build());
            }
        });
        return result;

    }

}